package com.course.finalproject.manager;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Parcelable;
import android.support.v4.content.LocalBroadcastManager;

import com.course.finalproject.Constants;
import com.course.finalproject.MyApplication;
import com.course.finalproject.model.Weather;
import com.course.finalproject.service.WeatherService;

/**
 * Class that handles the weather requests.
 * @author	Mariano Bessone <mariano.bessone @ tallertechnologies.com>
 * @since	2012-09-11
 */
public class WeatherManager {

	/** Weather parameters. */
	private double lat;
	private double lon;
	private int daysCount;
	/** List of weathers. */
	private List<Weather> weathers;
	/** Last date of weather update. */
	private Date lastWeatherUpdate;
	/** Boolean that indicates if there is a weather service request ongoing. */
	private boolean ongoingWeatherService;

	/** Local broadcast receiver for update the weather. */
	private BroadcastReceiver weatherReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			// Only actualizes the weather if it is fresh.
			if ( intent.getBooleanExtra(Constants.WEATHER_FRESH_KEY, false) ) {
				// If the list of weather is not empty actualizes the values.
				List<Weather> newWeathers = intent.getParcelableArrayListExtra(Constants.WEATHER_LIST_PARCEL_KEY);
				if ( !newWeathers.isEmpty() ) {
					// Copy to local list.
					weathers = newWeathers;
					// Save the actual time.
					lastWeatherUpdate = new Date();
				}
				// Weather request done.
				ongoingWeatherService = false;
			}
    	}
	};


	/**
	 * Constructor.
	 */
	public WeatherManager() {
		// No ongoing weather request at the beginning.
		ongoingWeatherService = false;
		// Create weathers list.
		weathers = new ArrayList<Weather>();
		// Initialize the date of last weather actualization on 1970.
		lastWeatherUpdate = new Date(0);
		// Register to receive a new weather update.
		LocalBroadcastManager.getInstance(MyApplication.getInstance()).registerReceiver(weatherReceiver, new IntentFilter(Constants.NEW_WEATHER_UPDATE));
	}
	
	/**
	 * Destructor.
	 */
	public void destructor() {
		// Unregister to do not receive a new weather update anymore.
		LocalBroadcastManager.getInstance(MyApplication.getInstance()).unregisterReceiver(weatherReceiver);
	}
	
	/**
	 * Sets the location and the extended days for retrieve the weather.
	 * 
	 * @param lat Latitude.
	 * @param lon Longitude.
	 * @param daysCount Weather extended days to retrieve.
	 */
	public void setWeatherParameters(double lat, double lon, int daysCount) {
		this.lat = lat;
		this.lon = lon;
		this.daysCount = daysCount;
	}
	
	/**
	 * Performs a weather request.
	 */
	public void doWeatherRequest() {
		ongoingWeatherService = true;

		Intent weatherIntent = new Intent(MyApplication.getInstance().getApplicationContext(), WeatherService.class); 
		weatherIntent.putExtra(Constants.WEATHER_LAT_KEY, lat);
		weatherIntent.putExtra(Constants.WEATHER_LON_KEY, lon);
		weatherIntent.putExtra(Constants.WEATHER_DAYS_COUNT, daysCount);
		MyApplication.getInstance().startService(weatherIntent);
	}

	/**
	 * This method gives to the weather local broadcast receivers a current weather.
	 * If there is a request ongoing then the weather will come to the receivers without do nothing here, otherwise
	 * it does a request or it broadcasts a weather cached, depending on the time which this method will be call.
	 */
	public void askForNewWeather() {
		if (!ongoingWeatherService) {
			if (new Date().getTime() > lastWeatherUpdate.getTime() + Constants.WEATHER_UPDATE_MINUTES * 60 * 1000) {
				doWeatherRequest();
			} else {
				// Make the non fresh response intent and broadcast it.
				Intent broadcastIntent = new Intent(Constants.NEW_WEATHER_UPDATE);
				broadcastIntent.putExtra(Constants.WEATHER_FRESH_KEY, false);
				broadcastIntent.putParcelableArrayListExtra(Constants.WEATHER_LIST_PARCEL_KEY, (ArrayList<? extends Parcelable>) weathers);
		        LocalBroadcastManager.getInstance(MyApplication.getInstance()).sendBroadcast(broadcastIntent);
			}
		}
	}
	
}
